package com.sanerzone.smscenter.api.http;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.RateLimiter;
import com.sanerzone.common.support.sequence.MsgId;
import com.sanerzone.smscenter.api.entity.ApiResult;
import com.sanerzone.smscenter.api.entity.ProcessResult;
import com.sanerzone.smscenter.api.util.InterfaceUtil;
import com.sanerzone.smscenter.biz.cache.AccountCacheHelper;
import com.sanerzone.smscenter.biz.cache.TemplateCacheHelper;
import com.sanerzone.smscenter.biz.message.SMSREQMessage;
import com.sanerzone.smscenter.biz.utils.SignHelper;
import com.sanerzone.smscenter.biz.utils.StringHelper;
import com.sanerzone.smscenter.common.tools.*;
import com.sanerzone.smscenter.common.web.BaseController;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/api/template")
public class SmsApiTemplateController extends BaseController{
    @Autowired
    private InterfaceUtil interfaceUtil;
    public static final int MAXSEND_NUM=100000;
    public static final int MINSEND_NUM=1000;
    public static final int MAXTEXTSEND_NUM=5;
    public static final int MAXREQ_NUM=500;

    public static Logger logger = LoggerFactory.getLogger(SmsApiTemplateController.class);
    
    @Autowired
    private MQHelper mQUtils;
    
//    @Autowired
//    private SmsTaskInterface smsTaskInterface;
//    @RequestMapping(value = "sms/test", method = RequestMethod.POST)
//    public void test(HttpServletRequest request, HttpServletResponse response){
//        Map pMap = getPostDataMap(request, response);
//    }


    @SuppressWarnings({"unchecked", "rawtypes"})
    @RequestMapping(value = "sms/send", method = RequestMethod.POST)
        public String smsSend(HttpServletRequest request, HttpServletResponse response){

            Map pMap = getPostDataMap(request, response);
            long time = System.currentTimeMillis();
            Map map = Maps.newHashMap();
            try{
                String userId = StringHelper.valueof(pMap.get("userid"));
                String ts = StringHelper.valueof(pMap.get("ts"));//时间戳
                String pSign = StringHelper.valueof(pMap.get("sign"));
                String appid = StringHelper.valueof(pMap.get("appid"));
                String groupid = StringHelper.valueof(pMap.get("groupid"));
                String gatewayId = StringHelper.valueof(pMap.get("gatewayId"));
                String sendTime=StringHelper.valueof( pMap.get("time"));
                String phones = StringHelper.valueof(pMap.get("mobile"));
                String submitId = StringHelper.valueof( pMap.get( "submitId" ));
                String key = userId+"_"+appid;
                //基础能数校验
                String result = ValidateHelper.validate(userId, appid, ts, pSign, request, response);
                if (!"0".equals(result)){//验证成功 等于0就不走这里了
                    return result;
                }

                //校验业务参数
                result = ValidateHelper.validateSmsParameter(pMap, request, response);
                if (!"0".equals(result)){//验证成功
                    return result;
                }
                if (phones.contains(",")) {
                    String speed = AccountCacheHelper.getStringValue(userId, "httpSpeed", "0");//发送速率
                    Double massSpeed = Double.parseDouble(speed);
                    if(massSpeed > 0){
                        RateLimiter limiter = AccountCacheHelper.getHttpSpeed("mass_" + userId);
                        limiter.acquire();
                    }
                } else {
                    int speed = AccountCacheHelper.getIntegerValue(key, "httpSpeed", -1);//发送速率
                    if(speed > 0){
                        //每个用户所允许传送的速度不一样
                        RateLimiter limiter = AccountCacheHelper.getHttpSpeed(userId);
                        limiter.acquire();
                    }
                }
                //校验定时发送时间
                String sendtime = StringHelper.valueof(pMap.get("time"));
                Date sendDatetime = null;
                if (StringHelper.isNotBlank(sendtime)){
                    sendDatetime = sendDatetime(sendtime);
                    if (sendDatetime == null){
                        return ValidateHelper.result("8", "time时间格式错误", null, response);
                    }
                }

                //校验手机号码的合法性

                ProcessResult<List<String>> processResult=ValidateHelper.validatePhones( phones,request,response );
                List<String> phonesList=processResult.getData();
                if(processResult.getResultFlag()==0){
                    return ValidateHelper.result("22", "群发号码数量超过限制", null, response);
                }
                int size=processResult.getPhones().split( "," ).length;
                phones=processResult.getPhones();//更新号码（剔除失败的号码）
                String accountGroupId = AccountCacheHelper.getStringValue(key, "serviceId", "");
    ////            //限制非行业用户每日测试发送次数
    //            if (!StringUtils.equals(accountGroupId,"10") && !StringUtils.equals(accountGroupId, "20")) {
    //                ProcessResult<String> prLimitSendTimeRes=InterfaceUtil.userSendLimitProcess( pMap, phonesList);
    //                if(prLimitSendTimeRes.getResultFlag()==0){
    //                    return ValidateHelper.result("23", "超出测试次数,非行业用户每天测试5次,每次最多5条,最少1000条起", null, response);
    //                }
    //            }

                //校验短信内容
                String templateid = StringHelper.valueof(pMap.get("templateid"));
                String smsContent = "";

                List<String> templateparam = Lists.newArrayList();
                //如果不是模板短信  目的就是为了填充内容
                if(StringHelper.isBlank(templateid)){
                    smsContent = StringEscapeUtils.unescapeHtml4(StringHelper.valueof(pMap.get("msgcontent")));
                    smsContent = smsContent.trim();
                    smsContent = SignHelper.formatContent(smsContent);

                    String sign = SignHelper.get(smsContent);//获取短信签名
                    if (StringHelper.isBlank(sign)){//如果签名为空
                        sign = AccountCacheHelper.getStringValue(userId, "forceSign", "");	//强制签名
                        if(StringHelper.isNotBlank(sign)) {
                            smsContent = "【"+sign+"】" + smsContent;
                        }
                    }
                }else{
                    //如果是模板短信   获取模板短信
                    templateparam = (List<String>)pMap.get("templateparam");
                    if(templateparam != null && templateparam.size() > 0){
                        String templateStatus = TemplateCacheHelper.getStatus(templateid, userId);//模板状态
                        if(!"1".equals(templateStatus)){//这里是短信模板不通过的情况
                            String msg = "短信模板不存在";
                            if("-2".equals(templateStatus)){
                                msg = "短信模板审核失败";
                            }else if("-1".equals(templateStatus)){
                                msg = "短信模板待审核";
                            }else if("0".equals(templateStatus)){
                                msg = "短信模板禁用";
                            }
                            return ValidateHelper.result("18", msg, null, response);
                        }
                        String template = TemplateCacheHelper.getTemplate(templateid);//获取模板内容

                        int maxParam = templateparam.size();
                        if(template.indexOf(("{"+maxParam+"}")) >= 0){//替换模板参数
                            for (int i=1;i<=maxParam;i++) {
                                template = template.replace("{"+i+"}", templateparam.get(i-1));
                            }
                        }else{
                            return ValidateHelper.result("19", "短信模板参数个数不匹配", null, response);
                        }

                        smsContent = template;
                    }else{
                        return ValidateHelper.result("17", "短信模板参数不能为空", null, response);
                    }
                }

                String sTemplateid = TemplateCacheHelper.getTemplateId(templateid);//获取源模板编号

                if(smsContent.length() > 600) {
                    return ValidateHelper.result("16", "短信内容过长", null, response);
                }

                // 执行发送
                int smsSize = StringHelper.smsSize(smsContent);
                String sendtermid = StringHelper.stripToEmpty(StringHelper.valueof(pMap.get("extnum")));//扩展号
                String customTaskid = StringHelper.valueof(pMap.get("messageid"));//客户任务ID
                //余额
                String amountKey = AccountCacheHelper.getAmountKey("sms", userId);
                // 扣款
                long amount = JedisUtils.decrBy(amountKey, smsSize*size);
                if (amount < 0){
                JedisUtils.incrBy(amountKey, smsSize*size);
                    return ValidateHelper.result("3", "余额不足", null, response);
                }
                //白名单的验证
                interfaceUtil.verifyWhiteList( phones,accountGroupId,userId,smsContent );
                Map<String,Object> paramValueMap = Maps.newHashMap();
                paramValueMap.put("templateId", sTemplateid);
                paramValueMap.put("paramValue", templateparam);
                String paramValue = JSON.toJSONString(paramValueMap);

                SMSREQMessage message = new SMSREQMessage();
                if (sendTime!=null&&(!sendTime.equals( "" ))){
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss" );
                    Date date=sdf.parse( sendTime );
                    boolean isToday= InterfaceUtil.isToday( date );
                    if (isToday==false){
                        return ValidateHelper.result("24", "发送时间只能为今天的时间", null, response);
                    }
                    message.setSendTime( date );
                }


//                //挑选出不发送百分比的号码，直接发往MT 置为成功
//                String sendRadioStr=AccountCacheHelper.getStringValue(userId, "sendRatio", "1");
//                Double sendRadio = null;
//                try {
//                    sendRadio= Double.parseDouble( sendRadioStr );
//                    if (sendRadio>1.0){
//                        sendRadio=1.0;
//                    }
//                }catch (Exception e){
//                    sendRadio=1.0;
//                }
//                ApiResult apiResult=null;
//                if (sendRadio!=1.0){
//                    //需要挑选出非白名单号码直接发送成功
//                    apiResult=InterfaceUtil.filterNotSendPhones( phones,sendRadio );
//                }
//
//                if (!"noNeed".equals( apiResult.getCode() )) {
//                    phones = apiResult.getAfterCutPhones();
//                    String cutedPhones = apiResult.getCutedPhones();
//                }
//


                String taskId = new MsgId(1000001).toString();
                message.setTaskid(taskId);
                message.setAccId(appid);
                message.setUserid(userId);
                message.setFeeType(AccountCacheHelper.getStringValue(userId+"_0", "feeType", "1"));
                message.setFeePayment("1");//默认值
                message.setCustomTaskid(customTaskid);
                message.setCustomServiceid(accountGroupId);
                message.setPhones(phones);
                message.setSendnumber(sendtermid);
                message.setMsgContent(smsContent);
                message.setSmsContentId(templateid);
                message.setSmsType("0");//短信
                message.setSourceGateWayId("HTTP");
                message.setSourceGateWayProto("HTTP");
                message.setMassFlag("0");//单个发送
                message.setReceiveTime(new Date());
                message.setParamValue(paramValue);
                message.setRegisteredDelivery(StringHelper.registeredDelivery(AccountCacheHelper.getStringValue(userId+"_"+appid, "callbackUrl", ""))?"1":"0");
                message.setDeliveryGateWayId("HTTP");
                message.setSubmitId( submitId );
                if (!Strings.isNullOrEmpty(gatewayId)){
                    message.setGatewayId(gatewayId);
                }
                if (!Strings.isNullOrEmpty(groupid)){
                    message.setGatewayGroup(groupid);
                }

                // 提交到REQ
                String msgid = mQUtils.sendSmsREQ("SINGLE", taskId, message);
                logger.info("HttpApi-Submit-REQ = taskid:{}, msgid:{}, time:{}",  message.getTaskid(), msgid, (System.currentTimeMillis()-time));

                // 提交队列失败
                if( "-1".equals(msgid)) {
                     return ValidateHelper.result("1", "提交失败", null, response);
                }

                // 提交队列成功
                map = Maps.newHashMap();
                map.put("taskid", message.getTaskid());
                if(processResult.getResultFlag()==1){
                    return ValidateHelper.result("0", "提交成功", map, response);

                }
//                if(processResult.getResultFlag()==1){
//                    SMSSQMessage smssqMessage=new SMSSQMessage();
//                    smssqMessage.setContent( smsContent );
//                    smssqMessage.setSubmitId( submitId );
//                    smssqMessage.setTaskId( taskId );
//                    smssqMessage.setUserId( userId );
//                    smssqMessage.setSubmitTime( new Date(  ) );
//                    smssqMessage.setCount( size );
//                    mQUtils.sendSmsRC( "1","1", smssqMessage);
//
//                    return ValidateHelper.result("0", "提交成功", map, response);
//                }
                Map<String, Object> errorMap = Maps.newHashMap();
                errorMap.put("errorCode", "22");
                errorMap.put("errorPhones",processResult.getData());
                errorMap.put("errorMsg", "部分号码提交失败,原因:号码不合法");
                map.put("errorData",errorMap);
                logger.info("HttpApi-Submit-REQ = taskid:{}, msgid:{}, time:{}, 失败号码：{}", message.getTaskid(), msgid, (System.currentTimeMillis()-time), map);
                return ValidateHelper.result("0", "提交成功", map, response);
            }catch (Exception e){
                e.printStackTrace();
                return ValidateHelper.result("1", "提交失败", null, response);
            }
        }

    @SuppressWarnings("rawtypes")
    public Map getPostDataMap(HttpServletRequest request, HttpServletResponse response){
        try{
            String charEncoding = request.getCharacterEncoding();
            if (charEncoding == null){
                charEncoding = "UTF-8";
            }
            String respText = StreamHelper.InputStreamTOString(request.getInputStream(), charEncoding);
            logger.info("sms api json: {}", respText);
            if(StringHelper.isNotBlank(respText)){
                return (Map) JSON.parseObject(respText, Map.class);
            }
        }catch (IOException e){

        }
        return null;
    }

    
    //	查询订单状态
    @RequestMapping(value = "sms/query")
    public String smsSendQuery(HttpServletRequest request, HttpServletResponse response){
        return null;
    }
    
    
    
    //	查询用户余额
    @RequestMapping(value = "sms/balance")
    public String smsSendBalance(HttpServletRequest request, HttpServletResponse response){
        String userId = request.getParameter("userid");
        String sign = request.getParameter("sign");
        String ts = request.getParameter("ts");
        String appid = request.getParameter("appid");
        
        String result = ValidateHelper.validate(userId, appid, ts, sign, request, response);
        if ("0".equals(result)){//验证成功
        	//余额
            String amountKey = AccountCacheHelper.getAmountKey("amount", "sms", userId);
            String money = JedisUtils.get(amountKey);
            logger.info("------------------------------------余额:" + money + "------------------------------------");
            Map<String, String> data = Maps.newHashMap();
            data.put("balance", String.valueOf(money));
            return ValidateHelper.result("0", "查询成功", data, response);
        }else{
            return result;
        }
    }
    
    // 获取敏感词
    @RequestMapping(value = "sms/keyword")
    public String keyword(HttpServletRequest request, HttpServletResponse response){
        String userId = request.getParameter("userid");
        String sign = request.getParameter("sign");
        
        String result = validateKeyword(userId, sign, request, response);
        if ("0".equals(result)){//验证成功
            String smsContent = request.getParameter("msgcontent");
            if (StringHelper.isBlank(smsContent)){
                return resultKeyword("2", "msgcontent参数不能为空", userId, "", response);
            }
            
            return resultKeyword("0", "查询成功", userId, "", response);//TODO 匹配敏感词 没有实现
        }else{
            return result;
        }
    }
    
    private String validateKeyword(String userId, String sign, HttpServletRequest request, HttpServletResponse response){
        // 校验 userId
        if (StringHelper.isBlank(userId)){
            return resultKeyword("2", "userid参数不能为空", userId, "", response);
        }
        // 校验 apikey
        if (StringHelper.isBlank(sign)){
            return resultKeyword("2", "sign参数不能为空", userId, "", response);
        }
        
        String ts = request.getParameter("ts");
        if (StringHelper.isBlank(ts)){
            return resultKeyword("2", "ts参数不能为空", userId, "", response);
        }
        
        //验证用户是否存在
        String curUserId = AccountCacheHelper.getStringValue(userId, "id", "");
        
        if (StringHelper.isBlank(curUserId)){
            return resultKeyword("4", "用户不存在", userId, "", response);
        }else{
        	int usedFlag = AccountCacheHelper.getIntegerValue(userId, "usedFlag", 1);
			if(usedFlag == 0) {  //账户禁用发送功能
				return resultKeyword("4", "用户不存在", userId, "", response);
			}
        	
            String whiteIP = AccountCacheHelper.getStringValue(userId, "whiteIP", "");
            String ip = IPHelper.getIpAddr(request);
            
            if(StringHelper.isBlank(whiteIP) || ("," + whiteIP + ",").indexOf("," + ip + ",") >= 0){//验证IP
                String apikey = AccountCacheHelper.getStringValue(userId, "apikey", "");
                String myMD5 = HttpRequest.md5(userId + ts + apikey);//MD5加密 md5(userid + ts + apikey)
                if (!sign.equals(myMD5)){//MD5验证
                    return resultKeyword("6", "MD5校验失败", userId, "", response);
                }
            }else{
                return resultKeyword("7", "IP校验失败", userId, "", response);
            }
        }
        
        return "0";
    }
    
    
//    @SuppressWarnings({"rawtypes", "unchecked"})
//    private String result(HttpServletResponse response, Map map){
//        String code = StringHelper.valueof(map.get("code"));
//        String msg = StringHelper.valueof(map.get("msg"));
//        String taskid = StringHelper.valueof(map.get("taskid"));
//        
//        
//        ApiResult entity = new ApiResult();
//        entity.setCode(code);
//        entity.setMsg(msg);
//        if (StringHelper.equals(code, "0")){
//            Map<String, String> tmp = Maps.newHashMap();
//            tmp.put("taskid", taskid);
//            entity.setData(tmp);
//        }
//        
//        return renderString(response, entity);
//        
//    }
    
    
    @SuppressWarnings({"unchecked", "rawtypes"})
    private String resultKeyword(String code, String msg, String userid, String keywords, HttpServletResponse response){
        
        ApiResult entity = new ApiResult();
        entity.setCode(code);
        entity.setMsg(msg);
        if (StringHelper.isNotBlank(keywords)){
            Map<String, String> map = Maps.newHashMap();
            map.put("keywords", keywords);
            entity.setData(map);
        }

        return renderString(response, entity);
    }
    
    public static Date sendDatetime(String sendTime){
        Date result = null;
        try{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            result = sdf.parse(sendTime);
        }catch (Exception err){
            logger.debug("时间格式错误: " + err.getMessage());
        }
        return result;
    }
    
    @RequestMapping(value = "sms/report")
    public String reportTest(HttpServletRequest request, HttpServletResponse response){
    	@SuppressWarnings("rawtypes")
		Map map = getPostDataMap(request, response);
    	return renderString(response, "ok", "application/json");
    }
    
    private String getTaskData(List<String> phoneList){
    	StringBuffer sb = new StringBuffer("");
    	for (String phone : phoneList) {
    		sb.append(phone).append("\r\n");
		}
    	return sb.toString();
    }
}
